/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hybris;

/**
 *
 * @author menderleit
 */
public class Vector3 implements Comparable<Vector3> {
    // 3D-Space coordinates.
    private double x, y, z;
    
    // 2D-Projected coordinates.
    private double px, py;
    
    // Screen-Space mapped coordinates.
    private int sx, sy;
    
    // Default constructor.
    public Vector3() {
        x = 0.0;
        y = 0.0;
        z = 0.0;
        px = 0.0;
        py = 0.0;
        sx = 0;
        sy = 0;
    }
    
    public Vector3(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
        px = 0.0;
        py = 0.0;
        sx = 0;
        sy = 0;
    }
    
    public Vector3 copy() {
        Vector3 nVec = new Vector3(x, y, z);
        return nVec;
    }
    
    public void project(double FOV) {
        px = x / z ;
        py = y / (z / FOV);
    }
    
    public void map(int screenWidth, int screenHeight) {
        int SW2 = screenWidth / 2;
        int SH2 = screenHeight / 2;
        sx = (int)(px * SW2 + SW2);
        sy = (int)(-py * SH2 + SH2);
    }
    
    public void set(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public void setX(double x) {
        this.x = x;
    }
    
    public void setY(double y) {
        this.y = y;
    }
    
    public void setZ(double z) {
        this.z = z;
    }
    
    public double getX() {
        return x;
    }
    
    public double getY() {
        return y;
    }
    
    public double getZ() {
        return z;
    }
    
    public int getSX() {
        return sx;
    }
    
    public int getSY() {
        return sy;
    }

    public Vector3 subtract(Vector3 v) {
        Vector3 sub = new Vector3(x-v.getX(), y-v.getY(), z-v.getZ());
        return sub;
    }
    
    public double dotProduct(Vector3 v) {
        double d = x*v.getX() + y*v.getY() + z*v.getZ();
        return d;
    }
    
    public Vector3 crossProduct(Vector3 v) {
        Vector3 cross = new Vector3(y*v.getZ()-z*v.getY(), z*v.getX()-x*v.getZ(), x*v.getY()-y*v.getX());
        return cross;
    }
    
    public double length() {
        double l = Math.sqrt(x*x+y*y+z*z);
        return l;
    }
    public Vector3 normalize() {
        double l = length();
        Vector3 n = new Vector3(x/l, y/l, z/l);
        return n;
    }
    
    public void move(Vector3 v3) {
        x += v3.getX();
        y += v3.getY();
        z += v3.getZ();
    }
    
    public void rotate(Vector3 v3) {
        double tx, ty, tz;
        // Rotate X
        ty = y * Math.cos(Math.toRadians(v3.getX())) - z * Math.sin(Math.toRadians(v3.getX()));
        z = y * Math.sin(Math.toRadians(v3.getX())) + z * Math.cos(Math.toRadians(v3.getX()));
        y = ty;
        
        // Rotate Y
        tx = x * Math.cos(Math.toRadians(v3.getY())) + z * Math.sin(Math.toRadians(v3.getY()));
        z = x * -(Math.sin(Math.toRadians(v3.getY()))) + z * Math.cos(Math.toRadians(v3.getY()));
        x = tx;
        
        // Rotate Z
        tx = x * Math.cos(Math.toRadians(v3.getZ())) - y * Math.sin(Math.toRadians(v3.getZ()));
        y = x * Math.sin(Math.toRadians(v3.getZ())) + y * Math.cos(Math.toRadians(v3.getZ()));
        x = tx;
    }
    
    @Override
    public int compareTo(Vector3 t) {
        int result = 0;
        if(this.z < t.getZ()) {
            result = 1;
        }
        if(this.z > t.getZ()) {
            result = -1;
        }
        return result;
    }
}
